/*
 * @Author: wuqingchun
 * @Date: 2024-07-16 10:39:30
 * @Description: 固定大小内存管理器
 * @LastEditors: wuqingchun
 * @LastEditTime: 2024-07-16 18:55:15
 */

#include <iostream>
#include <cstddef>

#include "mem_time.h"

class NextOnFreeList
{
public:
    NextOnFreeList* next;
};

class Rational
{
private:
    static constexpr int EXPANSION_COUNT = 32;
public:
    Rational(int iNumerator=0, int iDenominator=1):
        m_iNumerator(iNumerator),
        m_iDenominator(iDenominator)
    {
    }

    ~Rational()
    {

    }

    void* operator new(size_t ulSize)
    {
        if (freelist == nullptr)
        {
            __ExpandMemPool();
        }

        NextOnFreeList* head = freelist;
        freelist = head->next;

        return head;
    }

    void operator delete(void* pObj, size_t ulSize)
    {
        ((NextOnFreeList*)pObj)->next = freelist;
        freelist = (NextOnFreeList*)pObj;
    }

    static void newMemPool()
    {
        __ExpandMemPool();
    }

    static void deleteMemPool()
    {
        while (freelist != nullptr)
        {
            NextOnFreeList* next = freelist->next;
            delete freelist;
            freelist = next;
        }
    }

private:
    static void __ExpandMemPool()
    {
        size_t ulOneSize = sizeof(NextOnFreeList) > sizeof(Rational) ? sizeof(NextOnFreeList) : sizeof(Rational);

        for (int i = 0; i < EXPANSION_COUNT; i++)
        {
            NextOnFreeList* pNew = reinterpret_cast<NextOnFreeList*> (new (std::nothrow) char[ulOneSize]);
            if (pNew != nullptr)
            {
                pNew->next = freelist;
                freelist = pNew;
            }
        }
    }
private:
    static NextOnFreeList* freelist;
private:
    int m_iNumerator;
    int m_iDenominator;
};

NextOnFreeList* Rational::freelist = nullptr;

int main(int argc, char** argv)
{
    Rational* apobjRational[1000];
    Rational::newMemPool();

    uint64_t ui64BeginUS, ui64EndUS;
    
    TIMESTAMP_NOW_US(ui64BeginUS);
    // 开始计时
    for (int i = 0; i < 500; i++)
    {
        for (int j = 0; j < 1000; j++)
        {
            apobjRational[j] = new Rational(i);
        }

        for (int j = 0; j < 1000; j++)
        {
            delete apobjRational[j];
        }
    }

    TIMESTAMP_NOW_US(ui64EndUS);

    Rational::deleteMemPool();
    // 结束计时

    std::cout << "Elapsed(us): " << ui64EndUS - ui64BeginUS << std::endl;

    return 0;
}